import { Tabs, Steps, Callout } from "nextra/components";
import UniversalTabs from "../../components/UniversalTabs";

# Hatchet Lite Deployment

To get up and running quickly, you can deploy via the `hatchet-lite` image. This image is designed for development and low-volume use-cases.

<Steps>

### Prerequisites

This deployment requires [Docker](https://docs.docker.com/engine/install/) installed locally to work.

### Getting Hatchet Lite Running

<Tabs items={['Without existing Postgres Instance', 'With existing Postgres Instance']}>
  <Tabs.Tab>
Copy the following `docker-compose.hatchet.yml` file to the root of your repository:

```yaml filename="docker-compose.hatchet.yml" copy
version: "3.8"
name: hatchet-lite
services:
  postgres:
    image: postgres:15.6
    command: postgres -c 'max_connections=200'
    restart: always
    environment:
      - POSTGRES_USER=hatchet
      - POSTGRES_PASSWORD=hatchet
      - POSTGRES_DB=hatchet
    volumes:
      - hatchet_lite_postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d hatchet -U hatchet"]
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 10s
  hatchet-lite:
    image: ghcr.io/hatchet-dev/hatchet/hatchet-lite:latest
    ports:
      - "8888:8888"
      - "7077:7077"
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      RABBITMQ_DEFAULT_USER: "user"
      RABBITMQ_DEFAULT_PASS: "password"
      DATABASE_URL: "postgresql://hatchet:hatchet@postgres:5432/hatchet?sslmode=disable"
      SERVER_TASKQUEUE_RABBITMQ_URL: amqp://user:password@localhost:5672/
      SERVER_AUTH_COOKIE_DOMAIN: localhost
      SERVER_AUTH_COOKIE_INSECURE: "t"
      SERVER_GRPC_BIND_ADDRESS: "0.0.0.0"
      SERVER_GRPC_INSECURE: "t"
      SERVER_GRPC_BROADCAST_ADDRESS: localhost:7077
      SERVER_GRPC_PORT: "7077"
      SERVER_URL: http://localhost:8888
      SERVER_AUTH_SET_EMAIL_VERIFIED: "t"
      SERVER_LOGGER_LEVEL: warn
      SERVER_LOGGER_FORMAT: console
      DATABASE_LOGGER_LEVEL: warn
      DATABASE_LOGGER_FORMAT: console
    volumes:
      - "hatchet_lite_rabbitmq_data:/var/lib/rabbitmq"
      - "hatchet_lite_config:/config"

volumes:
  hatchet_lite_postgres_data:
  hatchet_lite_rabbitmq_data:
  hatchet_lite_config:
```

Then run `docker-compose -f docker-compose.hatchet.yml up` to get the Hatchet Lite instance running.

      </Tabs.Tab>
      <Tabs.Tab>

Copy the following `docker-compose.hatchet.yml` file to the root of your repository:

```yaml filename="docker-compose.hatchet.yml" copy
version: "3.8"
name: hatchet-lite
services:
  hatchet-lite:
    image: ghcr.io/hatchet-dev/hatchet/hatchet-lite:latest
    ports:
      - "8888:8888"
      - "7077:7077"
    environment:
      RABBITMQ_DEFAULT_USER: "user"
      RABBITMQ_DEFAULT_PASS: "password"
      DATABASE_URL: "postgresql://hatchet:hatchet@postgres:5432/hatchet?sslmode=disable"
      DATABASE_POSTGRES_PORT: "5432"
      DATABASE_POSTGRES_HOST: "postgres"
      SERVER_TASKQUEUE_RABBITMQ_URL: "amqp://user:password@localhost:5672/"
      SERVER_AUTH_COOKIE_DOMAIN: localhost
      SERVER_AUTH_COOKIE_INSECURE: "t"
      SERVER_GRPC_BIND_ADDRESS: "0.0.0.0"
      SERVER_GRPC_INSECURE: "t"
      SERVER_GRPC_BROADCAST_ADDRESS: localhost:7077
      SERVER_GRPC_PORT: "7077"
      SERVER_URL: http://localhost:8888
      SERVER_AUTH_SET_EMAIL_VERIFIED: "t"
      SERVER_LOGGER_LEVEL: warn
      SERVER_LOGGER_FORMAT: console
      DATABASE_LOGGER_LEVEL: warn
      DATABASE_LOGGER_FORMAT: console
    volumes:
      - "hatchet_lite_rabbitmq_data:/var/lib/rabbitmq"
      - "hatchet_lite_config:/config"

volumes:
  hatchet_lite_rabbitmq_data:
  hatchet_lite_config:
```

    </Tabs.Tab>

</Tabs>

### Accessing Hatchet Lite

Once the Hatchet Lite instance is running, you can access the Hatchet Lite UI at [http://localhost:8888](http://localhost:8888).

By default, a user is created with the following credentials:

```
Email: admin@example.com
Password: Admin123!!
```

### Generate a `.env` file

You can generate a `.env` file as follows:

```sh
cat <<EOF > .env
HATCHET_CLIENT_TOKEN="$(docker compose -f docker-compose.hatchet.yml exec hatchet-lite /hatchet-admin token create --config /config --tenant-id 707d0855-80ab-4e1f-a156-f1c4546cbf52 | xargs)"
HATCHET_CLIENT_TLS_STRATEGY=none
EOF
```

<Callout type="info" emoji="🪓">

You can also generate an API token by logging in and navigating to the "General" settings page, clicking on the "API Tokens" tab, and then clicking "Create API Token".

</Callout>

### Run your first worker

<UniversalTabs items={['Python', 'Typescript', 'Go']}>
  <Tabs.Tab>
Make sure you have the following dependencies installed:

```sh
pip install python-dotenv
pip install hatchet-sdk
```

We are using [`python-dotenv`](https://pypi.org/project/python-dotenv/) to load the environment variables from a `.env` file. This isn't required, and you can use your own method to load environment variables.

Create a `worker.py` file with the following contents:

```python filename="worker.py" copy
from hatchet_sdk import Hatchet
from dotenv import load_dotenv

load_dotenv()

hatchet = Hatchet(debug=True)

@hatchet.workflow(name="first-python-workflow",on_events=["user:create"])
class MyWorkflow:
    @hatchet.step()
    def step1(self, context):
        return {
            "result": "success"
        }

worker = hatchet.worker('first-worker')
worker.register_workflow(MyWorkflow())

worker.start()
```

Open a new terminal and start the worker with:

```sh
python3 worker.py
```

  </Tabs.Tab>
  <Tabs.Tab>
First, install `@hatchet-dev/typescript-sdk` via:

```sh npm2yarn
npm i @hatchet-dev/typescript-sdk
npm i dotenv
```

We also use `dotenv` to load the environment variables from a `.env` file. This isn't required, and you can use your own method to load environment variables.

Next, copy the following code into a `worker.ts` file:

```typescript filename="worker.ts" copy
import Hatchet, { Workflow } from "@hatchet-dev/typescript-sdk";
import dotenv from "dotenv";

dotenv.config();

const hatchet = Hatchet.init();

const workflow: Workflow = {
  id: "first-typescript-workflow",
  description: "This is my first workflow",
  on: {
    event: "user:create",
  },
  steps: [
    {
      name: "step1",
      run: async (ctx) => {
        console.log(
          "starting step1 with the following input",
          ctx.workflowInput(),
        );

        return {
          result: "success!",
        };
      },
    },
  ],
};

hatchet.run(workflow);
```

Next, modify your `package.json` to include a script to start:

```json
{
  // ...rest of your `package.json`
  "scripts": {
    // ...existing scripts
    "worker": "npx ts-node worker.ts"
  }
}
```

Now to start the worker, in a new terminal run:

```sh npm2yarn
npm run worker
```

  </Tabs.Tab>
  <Tabs.Tab>
  In a new Go project, copy the following code into a `main.go` file:

```go filename="main.go" copy
package main

import (
	"fmt"

	"github.com/joho/godotenv"

	"github.com/hatchet-dev/hatchet/pkg/client"
	"github.com/hatchet-dev/hatchet/pkg/cmdutils"
	"github.com/hatchet-dev/hatchet/pkg/worker"
)

type stepOutput struct{}

func main() {
	err := godotenv.Load()
	if err != nil {
		panic(err)
	}

	c, err := client.New()

	if err != nil {
		panic(fmt.Sprintf("error creating client: %v", err))
	}

	w, err := worker.NewWorker(
		worker.WithClient(
			c,
		),
		worker.WithMaxRuns(1),
	)
	if err != nil {
		panic(fmt.Sprintf("error creating worker: %v", err))
	}

	err = w.RegisterWorkflow(
		&worker.WorkflowJob{
			Name:        "simple-workflow",
			Description: "Simple one-step workflow.",
      On:          worker.Events("simple"),
			Steps: []*worker.WorkflowStep{
				worker.Fn(func(ctx worker.HatchetContext) (result *stepOutput, err error) {
					fmt.Println("executed step 1")

					return &stepOutput{}, nil
				},
				).SetName("step-one"),
			},
		},
	)
	if err != nil {
		panic(fmt.Sprintf("error registering workflow: %v", err))
	}

	interruptCtx, cancel := cmdutils.InterruptContextFromChan(cmdutils.InterruptChan())
	defer cancel()

	cleanup, err := w.Start()
	if err != nil {
		panic(fmt.Sprintf("error starting worker: %v", err))
	}

	<-interruptCtx.Done()
	if err := cleanup(); err != nil {
		panic(err)
	}
}
```

Next, run the following command to start the worker:

```sh
go run main.go
```

</Tabs.Tab>
</UniversalTabs>

### Run your first workflow

The worker is now running and listening for steps to execute. You should see your first worker registered in the `Workers` tab of the Hatchet dashboard:

![Quickstart 1](/quickstart-1.png)

You can now trigger your first workflow by navigating to the `Workflows` tab, selecting your workflow, and clicking the top right "Trigger workflow" button:

![Quickstart 2](/quickstart-2.png)

That's it! You've successfully deployed Hatchet and run your first workflow.

</Steps>
